import os
import sys
import peermanager
import filemanager
import pinger
import server

##Pretty print peer
def out_peer(peer):
  name, neighbors, ip, port = peer
  print name + " (" + str(neighbors) + ", " + ip + ":" + str(port) + ")"

##Pretty print peer list
def out_list(plist):
  for peer in plist:
    out_peer(peer)

##Main method including the basic user interface to interact with program
def main(name, neighbors, port):
  pman = peermanager.PeerManager(name, neighbors, port)
  fman = filemanager.FileManager(pman)
  pman.fman = fman
  serve = server.Server(pman, fman, port)
  ping = pinger.Pinger(pman)
  
  walker_ttl = 3
  walker_k = 3
  
  serve.setDaemon(1)
  ping.setDaemon(1)
    
  serve.start()
  ping.start()
  
  while 1:
    try:
      strings = raw_input(name + "> ").split()
    except EOFError:
      pass
          
    if strings[0] == "hello":
      ip, port = strings[1].split(":")
      pman.hello(ip, int(port))
      
      print "Peer list:"
      out_list(pman.plist)

      print "\nNeighborhood:"
      out_list(pman.nlist)
      
    elif strings[0] == "plist":
      out_list(pman.plist)
        
    elif strings[0] == "nlist":
      peers = []
      out = False
      
      i = 1
      while i < len(strings):
        if strings[i] != "-o":
          peers.append(strings[i])
        elif strings[i] == "-o":
          out = True
          f = open(strings[i + 1], "w")
          if len(peers) == 0: peers.append(pman.name)
          f.write(pman.creategraph(peers))
          f.close()
        i += 1
        
      if not out:
        if len(peers) == 0: peers.append(pman.name)
        print pman.creategraph(peers)
        
    elif strings[0] == "flist":
      flist = fman.getstructflist()
      print "File list:"
      for fil in flist:
        print fil[0][0] + " " + ", ".join(fil[1:])
      
    elif strings[0] == "find":
      print "Searching..."
      def out(fname, peer):
        print "File found: " + fname + " -> " + str(peer)
      
      pman.init_search(strings[1], walker_ttl, walker_k, out)
        
    elif strings[0] == "exit":
      sys.exit(0)
      
    elif strings[0] == "random":
      filemanager.addrandom(fman)
      print "Random files added from " + fman.dir
      
    elif strings[0] == "nflists":
      print fman.nflists
      
    elif strings[0] == "cd":
      fman._dir += strings[1] + "/"
      print fman._dir
      
    elif strings[0] == "get":
      ip, port = strings[1].split(":")
      print "Download started..."
      fman.fileget(ip, int(port), strings[2])
      print "Download finished"
      
    elif strings[0] == "fget":
      print "Searching..."
      
      def download(fname, peer, pman = pman, fman = fman):
        print fname + " " + str(peer) + " " + fman._dir
        name, neighbors, ip, port = peer
        if name != pman.name:
          print "Download started..."
          print ip + ", " + str(port) + ", " + fname
          fman.fileget(ip, port, fname)
          print "Download finished"
        else:
          print "You already have the file"
        
      pman.init_search(strings[1], walker_ttl, walker_k, download)
      
    elif strings[0] == "walker":
      walker_k = int(strings[1])
      walker_ttl = int(strings[2])
      print "Walker: k=" + str(walker_k) + " ttl=" + str(walker_ttl)

if __name__ == "__main__":
  main(sys.argv[1], int(sys.argv[2]), int(sys.argv[3]))
